package com.own.business.push.module.flyme.client;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.own.business.push.core.base.BasePushClientMethod;
import com.own.business.push.core.model.MessagePushContentModel;
import com.own.business.push.module.flyme.property.PushFlymeProperty;
import com.own.component.common.util.encrypt.EncryptUtil;
import com.own.component.common.util.list.ListUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * PushFlymeClient
 *
 * @author chenxueli
 * @date 2023-11-16 13:27:15
 */
@Slf4j
@Component
public class PushFlymeClient implements BasePushClientMethod {

    private static final String HOST = "https://server-api-push.meizu.com";

    @Resource
    private PushFlymeProperty pushFlymeProperty;

    /**
     * 全量推送
     *
     * @param contentModel 内容
     */
    @Override
    public void all(MessagePushContentModel contentModel) {
        log.info("魅族全量推送暂不支持");
    }

    /**
     * 注册id推送
     *
     * @param regId        注册id列表
     * @param contentModel 内容
     */
    @Override
    public void regId(String regId, MessagePushContentModel contentModel) {
        var data = new HashMap<String, Object>();
        data.put("appId", pushFlymeProperty.getAppId());
        data.put("pushIds", regId);
        data.put("messageJson", JSON.toJSONString(buildContent(contentModel)));
        var sign = getSignature(data);
        data.put("sign", sign);
        var request = HttpRequest.post(HOST + "/garcia/api/server/push/varnished/pushByPushId")
                .contentType("application/x-www-form-urlencoded")
                .charset("UTF-8")
                .form(data)
                .execute();
        var body = request.body();
        log.info("魅族推送结果:{}", body);
    }

    /**
     * 注册id推送
     *
     * @param regIdList    注册id列表
     * @param contentModel 内容
     */
    @Override
    public void regId(List<String> regIdList, MessagePushContentModel contentModel) {
        // 注册id推送单次最多100个
        ListUtil.groupList(regIdList, 100).forEach(values -> {
            var data = new HashMap<String, Object>();
            data.put("appId", pushFlymeProperty.getAppId());
            data.put("pushIds", String.join(",", values));
            data.put("messageJson", JSON.toJSONString(buildContent(contentModel)));
            var sign = getSignature(data);
            data.put("sign", sign);
            var request = HttpRequest.post(HOST + "/garcia/api/server/push/varnished/pushByPushId")
                    .contentType("application/x-www-form-urlencoded")
                    .charset("UTF-8")
                    .form(data)
                    .execute();
            var body = request.body();
            log.info("魅族推送结果:{}", body);
        });
    }

    /**
     * 别名推送信息
     *
     * @param alias        别名
     * @param contentModel 内容
     */
    @Override
    public void alias(String alias, MessagePushContentModel contentModel) {
        var data = new HashMap<String, Object>();
        data.put("appId", pushFlymeProperty.getAppId());
        data.put("alias", alias);
        data.put("messageJson", JSON.toJSONString(buildContent(contentModel)));
        var sign = getSignature(data);
        data.put("sign", sign);
        var request = HttpRequest.post(HOST + "/garcia/api/server/push/varnished/pushByAlias")
                .contentType("application/x-www-form-urlencoded")
                .charset("UTF-8")
                .form(data)
                .execute();
        var body = request.body();
        log.info("魅族推送结果:{}", body);
    }

    /**
     * 别名推送信息
     *
     * @param aliasList    别名列表
     * @param contentModel 内容
     */
    @Override
    public void alias(List<String> aliasList, MessagePushContentModel contentModel) {
        // 别名推送单次最多1000个
        ListUtil.groupList(aliasList, 100).forEach(values -> {
            var data = new HashMap<String, Object>();
            data.put("appId", pushFlymeProperty.getAppId());
            data.put("alias", String.join(",", values));
            data.put("messageJson", JSON.toJSONString(buildContent(contentModel)));
            var sign = getSignature(data);
            data.put("sign", sign);
            var request = HttpRequest.post(HOST + "/garcia/api/server/push/varnished/pushByAlias")
                    .contentType("application/x-www-form-urlencoded")
                    .charset("UTF-8")
                    .form(data)
                    .execute();
            var body = request.body();
            log.info("魅族推送结果:{}", body);
        });
    }

    /**
     * 构造内容
     *
     * @param contentModel 内容
     * @return 内容
     */
    private JSONObject buildContent(MessagePushContentModel contentModel) {
        var data = new JSONObject();
        var noticeBarInfo = new JSONObject();
        noticeBarInfo.put("noticeBarType", 0);
        noticeBarInfo.put("title", contentModel.getNotificationTitle());
        noticeBarInfo.put("content", contentModel.getContent());
        data.put("noticeBarInfo", noticeBarInfo);

        var clickTypeInfo = new JSONObject();
        clickTypeInfo.put("clickType", 3);
        clickTypeInfo.put("customAttribute", JSON.toJSONString(contentModel.getExtras()));
        data.put("clickTypeInfo", clickTypeInfo);

        return data;
    }

    /**
     * 获取鉴权信息
     *
     * @param paramMap 请求参数
     * @return md5摘要
     */
    private String getSignature(Map<String, Object> paramMap) {
        // 先将参数以其参数名的字典序升序进行排序
        var sortedParams = new TreeMap<>(paramMap);
        var entries = sortedParams.entrySet();
        // 遍历排序后的字典，将所有参数按"key=value"格式拼接在一起
        var builder = new StringBuilder();
        for (var param : entries) {
            builder.append(param.getKey()).append("=").append(param.getValue());
        }
        builder.append(pushFlymeProperty.getSecret());
        log.debug("base string is:{}", builder);
        // 使用MD5对待签名串求签
        return EncryptUtil.MD5.encrypt(builder);
    }

    /**
     * 推送发送的名称
     *
     * @return 名称
     */
    @Override
    public String name() {
        return "flyme";
    }

}
